Skip to content

Conversation

JesusRojass
Copy link
Contributor

Replace async notification observer registration with synchronous registration
to eliminate timing-dependent crashes when objects are deallocated quickly.

Fixes #14273 (Link)

Discussion

The FPRTraceBackgroundActivityTracker class had a race condition during initialization where notification observers were registered asynchronously using dispatch_async(dispatch_get_main_queue()). This created a timing window where the tracker object could be deallocated before the async block executed, causing crashes when the block tried to call addObserver: with a deallocated self reference.

The crash occurred when:

  • FPRTraceBackgroundActivityTracker is created
  • Async observer registration is queued to main thread
  • Object is deallocated before async block executes
  • Async block runs with dangling self pointer → EXC_BAD_ACCESS

My solution involves to replace the asynchronous observer registration with synchronous registration to eliminate the race condition entirely

Testing

  • Added testRapidCreationAndDeallocation_noRaceCondition to verify fix
  • Added thread safety tests for background thread initialization
  • Added crash reproduction test class to demonstrate original bug
  • All existing tests continue to pass

API Changes

  • No API Changes

Replace async notification observer registration with synchronous registration
to eliminate timing-dependent crashes when objects are deallocated quickly.

Fixes firebase#14273
@JesusRojass
Copy link
Contributor Author

JesusRojass commented Oct 6, 2025

@visumickey Created PR Here

@JesusRojass JesusRojass marked this pull request as ready for review October 6, 2025 05:52
@JesusRojass
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses a critical race condition in FPRTraceBackgroundActivityTracker by switching from asynchronous to synchronous notification observer registration. The solution is robust, handling initialization from both main and background threads correctly to prevent deadlocks. The accompanying tests are comprehensive, not only verifying the fix under race conditions but also including a clear reproduction case for the original bug, which is excellent for future reference. The code is clean and the changes are well-explained. I have one minor suggestion in the tests to improve clarity.

@JesusRojass
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Excellent work on this pull request. You've correctly identified and fixed a critical race condition in FPRTraceBackgroundActivityTracker by replacing the asynchronous observer registration with a synchronous approach. The use of if ([NSThread isMainThread]) followed by dispatch_sync is a robust pattern that ensures thread safety and prevents the deallocation issue. The new unit tests are thorough and provide great coverage for the fix, including a specific test to reproduce and verify the absence of the race condition. I have one minor suggestion regarding code style for better maintainability.

@JesusRojass
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively resolves a race condition crash in FPRTraceBackgroundActivityTracker by replacing asynchronous notification observer registration with a synchronous approach. The implementation correctly handles object initialization from both main and background threads, and the new unit tests are comprehensive, verifying the fix under various conditions, including rapid allocation/deallocation cycles. I have one minor suggestion to consolidate a redundant test case, but overall this is an excellent fix.

@JesusRojass
Copy link
Contributor Author

@visumickey you can review from here, I added some of the Gemini suggestions (though idk if they where any good)

lmk if anything!

Capture strong self during async observer registration
@JesusRojass
Copy link
Contributor Author

@visumickey Made new changes and added commit, I also re tested everything and it seems fine

Screenshot 2025-10-06 at 4 43 59 p m

Add a Check before calling registerNotificationObservers to make the approach safer and address a nit pick of a duplicate / similar test
@visumickey visumickey requested a review from ncooke3 October 7, 2025 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash at FPRTraceBackgroundActivityTracker.m
3 participants